// Copyright (c) 2023 Huawei Device Co., Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Basic example of event_handler.

use ylong_light_actor::event_handler::{
    DefaultType, EventRunner, InnerEvent, Priority, ToEventHandler, ToEventHandlerExt,
};

// Defines Event ID.
const EVENT_ID_ZERO: u32 = 0;
const EVENT_ID_ONE: u32 = 1;

// Defines user struct.
struct MyEvent {
    data: u32,
}

// Makes user struct an "EventHandler", and defines process_event method for the "EventHandler".
impl ToEventHandler for MyEvent {
    fn process_event(&mut self, event: &InnerEvent<DefaultType>) {
        match event.id() {
            EVENT_ID_ZERO | EVENT_ID_ONE => {
                self.data += 1;
                println!("get id {}, data {}", event.id(), self.data)
            }
            _ => {
                println!("get wrong id {}", event.id())
            }
        }
    }
}

#[tokio::main()]
async fn main() {
    // 1. Starts an "EventRunner", and gets a handle to it.
    let runner = EventRunner::create().unwrap();
    let runner_handle = runner.handle();

    // 2. Starts a new thread, and runs the dispatcher on the thread. The thread will run forever
    // until handle.stop() be called.
    let join = std::thread::spawn(move || runner.run());

    // 3. Starts an EventHandler on the EventRunner.
    let handler = MyEvent { data: 0 }.to_event_handler(&runner_handle);

    // 4. Sends events and tasks to the EventHandler.
    handler
        .send_event(InnerEvent::new(EVENT_ID_ZERO), 200, Priority::Low)
        .unwrap();
    handler
        .post_task(|| println!("hello"), "hello_task", 300, Priority::Low)
        .unwrap();
    handler
        .send_sync_event(InnerEvent::new(EVENT_ID_ONE), 100, Priority::Low)
        .await
        .unwrap();
    handler
        .post_sync_task(|| println!("world"), "world_task", 400, Priority::Low)
        .await
        .unwrap();

    // 5. Stops the EventRunner.
    runner_handle.stop();
    join.join().unwrap();
}
